package com.appspot.gaeforum309.db;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.appspot.gaeforum309.core.ForumAPI;
import com.appspot.gaeforum309.pathing.Action;
import com.appspot.gaeforum309.pathing.PathableClass;
import com.appspot.gaeforum309.pathing.PathBuilder.IPathable;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

// TODO: Add a possibility to remove a comment.
// On a removed comment, the comment is conserved in the data base, but a field Removed is set to 1, and content will be erased in the future.
// (after a validation of admin)
// For a removed comment, a "Removed by author" string is used as message content in the showing message.

@PersistenceCapable
public class DBComment implements IPathable {
	public static final String tagName = "Comment";
	
	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
	
	@Persistent
	private String text;
	
	@Persistent
	private Key conversationKey;
	
	@Persistent
	private Key userAuthorKey;
	
	@Persistent
	private Date dateComment;
	
	public static final PathableClass pathable = new PathableClass(tagName, DBConversation.tagName){

		@Override
		public IPathable getObject(String value) {
			return DBComment.getComment(value);
		}

		@Override
		public void fillAction(Action.ActionType actionType, Action action) {
			switch(actionType)
			{
			case createChild:
				action.addField("Comment", Action.FieldType.longtext, "");
				break;	
			}
		}
	};

	public DBComment(String text, Key conversationKey, Key userKey) {
		super();
		this.text = text;
		this.conversationKey = conversationKey;
		this.userAuthorKey = userKey;
		this.dateComment = new Date();
	}
	
	public static DBComment getComment(String keystr)
	{
		Key key = KeyFactory.stringToKey(keystr);
		if(key == null)
			return null;
		
		DBComment res = (DBComment)PMF.pm().getObjectById(DBComment.class, key);
		return res;
	}
	
	public String getTextComment() {
		return text;
	}

	public void setComment(String comment) {
		this.text = comment;
	}

	public Key getKey() {
		return key;
	}

	public Key getConversationKey() {
		return conversationKey;
	}

	public Key getUserKey() {
		return userAuthorKey;
	}
	
	public DBUser getAuthor() {
		return DBUser.getUser(getUserKey());
	}

	public Date getDateDiscription() {
		return dateComment;
	}
	
	public String getKeyStr()
	{
		return KeyFactory.keyToString(getKey());
	}

	@Override
	public String getParentKeyStr() {
		return KeyFactory.keyToString(conversationKey);
	}

	@Override
	public String label() {
		return "Message";
	}
	
	public static DBComment createComment(DBConversation conversation, String text, DBUser author)
	{
		DBComment comment = new DBComment(text, conversation.getKey(), author.getKey());
		
		PMF.pm().makePersistent(comment);
		
		conversation.setDateLastComment(comment.dateComment);
		
		return comment;
	}
	
	public static List<DBComment> getAllCommentsOfConversation(DBConversation con)
	{
		Query q = PMF.pm().newQuery(DBComment.class);	
		q.setFilter("conversationKey == argConversation");
		q.setOrdering("dateComment asc");
		q.declareParameters("com.google.appengine.api.datastore.Key argConversation");
	
		@SuppressWarnings("unchecked")
		List<DBComment> res = (List<DBComment>)q.execute(con.getKey());
	
		return res;
	}
	
	public static List<DBComment> getCommentsOfConversation(DBConversation con, long first, long last)
	{
		Query q = PMF.pm().newQuery(DBComment.class);	
		q.setFilter("conversationKey == argConversation");
		q.setOrdering("dateComment asc");
		q.setRange(first, last);
		q.declareParameters("com.google.appengine.api.datastore.Key argConversation");
		
		@SuppressWarnings("unchecked")
		List<DBComment> res = (List<DBComment>)q.execute(con.getKey());
	
		return res;
	}
	
	@Override
	public PathableClass getPathable() {
		return pathable;
	}

	@Override
	public List<? extends IPathable> getChilds(int fromNumber, int toNumber) {
		return new ArrayList<IPathable>();
	}

	@Override
	public List<? extends IPathable> getChilds() {
		return new ArrayList<IPathable>();
	}

	@Override
	public boolean authorizedAction(Action.ActionType actionType) {
		switch(actionType)
		{
		case createChild:
			if(ForumAPI.loggedUser())
				return true;
			else
				return false;		
		}
		return false;
	}

	@Override
	public boolean applyAction(Action action) {
		// TODO Auto-generated method stub
		return false;
	}
}
